package com.hq.learnmybatisplus.controller;


import cn.hutool.core.util.NumberUtil;
import com.hq.learnmybatisplus.dao.MyTreeNode;
import com.hq.learnmybatisplus.entity.PubRegionEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
public class TreeTest {

    @Autowired
    com.hq.learnmybatisplus.dao.TreeDao TreeDao;

    @RequestMapping("test")
    public List<MyTreeNode> list() {
        List<PubRegionEntity> dataList = TreeDao.mySelectList();
        List<MyTreeNode> myTreeNodeList = new ArrayList<>();
        List<MyTreeNode> leafLists = new ArrayList<>();
        //数据封装
        for (PubRegionEntity pub : dataList) {
            MyTreeNode myTreeNode = new MyTreeNode();
            myTreeNode.setLabel(pub.getName());
            myTreeNode.setYourName(pub.getYourName());
            myTreeNode.setYourNm(pub.getYourNm());
            myTreeNode.setLevel(pub.getLevel());
            myTreeNode.setId(pub.getCityCode());
            myTreeNode.setValue(pub.getArea());
            myTreeNode.setChildren(new ArrayList<>());
            myTreeNode.setPid(pub.getParentCode());
            myTreeNodeList.add(myTreeNode);
            //最底层数据单独封装
            if (pub.getLevelType() == 6) {
                leafLists.add(myTreeNode);
            }
        }
        Map<String, MyTreeNode> myTreeNodeMap = myTreeNodeList.stream().collect(Collectors.toMap(k -> {
            if (k.getYourNm() != null) {
                return k.getYourNm() + k.getId();
            } else {
                return k.getId();
            }
        }, v -> v));

        Map<String, Object> leafMap = leafLists.stream().collect(Collectors.toMap(k -> k.getYourNm() + k.getId(), v -> v));
        // 设置每个节点的值
        for (String id_ : leafMap.keySet()) {
            MyTreeNode o = (MyTreeNode) leafMap.get(id_);
            setParentNodeValue(myTreeNodeMap, id_, o.getValue());
        }
        MyTreeNode parent = myTreeNodeMap.get("BFD558A034");
        List<MyTreeNode> excludeNullTreeNodes = myTreeNodeList.stream().filter(item -> item.getValue() != 0.0).collect(Collectors.toList());
        //---------生成有值的树
        List<MyTreeNode> tree = listToTree(excludeNullTreeNodes, "BFD558A034");
        System.out.println(1);
        return tree;

    }

    /**
     * 把根节点的值赋值到所有的上级
     *
     * @param myTreeNodeMap 所有数据
     * @param LeafId        最底层数据ID
     * @param value         最底层数据的值
     */
    private static void setParentNodeValue(Map<String, MyTreeNode> myTreeNodeMap, String LeafId, double value) {
        MyTreeNode node = myTreeNodeMap.get(LeafId);
        if (node == null || node.getValue() == 0.0) {
            return;
        }
        MyTreeNode pNode = myTreeNodeMap.get(node.getPid());
        if (pNode != null) {
            // 将子节点的值赋给父节点
            pNode.setValue(NumberUtil.add(value, pNode.getValue()));
            // 更新节点数据
            myTreeNodeMap.put(pNode.getId(), pNode);
            setParentNodeValue(myTreeNodeMap, pNode.getId(), value);
        }
    }


    public static List<MyTreeNode> listToTree(List<MyTreeNode> list, String rootId) {
        List<MyTreeNode> tree = new ArrayList<>();
        Map<String, MyTreeNode> map = new HashMap<>();
        // 将所有的数据，以键值对的形式装入map中
        for (MyTreeNode node : list) {
            // 去除冗余的子节点
            node.setChildren(new ArrayList<MyTreeNode>());
            if (node.getYourNm() != null) {
                map.put(node.getId() + node.getYourNm(), node);
            } else {
                map.put(node.getId(), node);
            }
        }
        for (MyTreeNode node : list) {
            // 如果id是父级的话就放入tree中
            if (node.getId().equals(rootId)) {
                tree.add(node);
            } else {
                // 子级通过父id获取到父级的类型
                MyTreeNode parent = map.get(node.getPid());
                // 父级获得子级，再将子级放到对应的父级中
                if (parent != null) {
                    parent.getChildren().add(node);
                }
            }
        }
        return tree;
    }
}
